<template>
    <div style="height: 100%;display: flex;justify-content: center;" v-if="!form.menuId">
        <el-empty :image-size="100" description="请选择左侧菜单后操作"></el-empty>
    </div>
    <el-row v-else :gutter="40">
        <el-col :lg="24">
            <div style="display: flex; justify-content: space-between">
                <h2>编辑菜单</h2>
                <div>
                    <el-button type="primary" :loading="loading" v-auth="'menu:update'" round @click="onSaveMenu()"></el-button>
                    <el-button type="danger"  :loading="loading" v-auth="'menu:delete'" round @click="remove(form)"></el-button>
                </div>
            </div>
            <el-form ref="menuFormRef" :model="form" :rules="rules" label-width="80px">
                <el-form-item prop="menuId" v-show="false">
                    <el-input v-model="form.menuId"/>
                </el-form-item>
                <el-row :gutter="10">
                    <el-col :span="12">
                        <el-form-item label="类型" prop="type">
                            <el-select v-model="form.type">
                                <el-option v-for="(item, index) in enums['type']" :key="index" :label="item.label" :value="item.value"/>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="图标" prop="icon">
                            <m-icon-select v-model="form.icon" clearable></m-icon-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="10">
                    <el-col :span="12">
                        <el-form-item label="显示名称" prop="title">
                            <el-input v-model="form.title" clearable placeholder="显示名字"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="所属项目" prop="code">
                            <el-select v-model="form.code" clearable placeholder="所属项目">
                                <el-option v-for="(item, index) in enums['code']" :key="index" :label="item.label" :value="item.value"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="10">
                    <el-col :span="12">
                        <el-form-item label="上级菜单" prop="parentId">
                            <el-tree-select v-model="form.parentId"
                                            :accordion="true"
                                            :check-strictly="true"
                                            :data="menus"
                                            node-key="menuId"
                                            placeholder=""/>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="授权标识" prop="perms">
                            <el-input v-model="form.perms" clearable placeholder="授权标识"></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="10">
                    <el-col :span="12">
                        <el-form-item label="访问路径" prop="path">
                            <el-input v-model="form.path" clearable placeholder="访问路径"></el-input>
                            <div class="el-form-item-msg">如果是外部链接、Iframe直接填写对应URL之后携带‘,_self’，例如：https://cn.vitejs.dev/,_self</div>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="页面路径" prop="component">
                            <el-input v-model="form.component" clearable placeholder="页面路径">
                                <template v-if="form.component && form.component !== 'PageView' && form.component.indexOf('http') !== 0"  #suffix>
                                    <el-text type="primary">
                                        /src/view{{form.component}}/index.vue
                                    </el-text>
                                </template>
                            </el-input>
                            <div class="el-form-item-msg">如果是内部链接、Iframe直接填写对应URL，例如：https://cn.vitejs.dev/</div>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="10">
                    <el-col :span="12">
                        <el-form-item label="排序" prop="orderNum">
                            <el-input-number v-model="form.orderNum" :min=0 controls-position="right" style="width: 100%;"/>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12"></el-col>
                </el-row>
            </el-form>
        </el-col>
        <el-col :lg="24">
            <h2>操作按钮</h2>
            <form-table v-model="buttons" :addTemplate="buttonDataTemplate" placeholder="暂无匹配相关操作按钮信息" v-loading="buttonLoading">
                <template #create="{template}">
                    <el-button circle plain type="primary" v-auth="'menu:add'" @click="onCreateOrUpdateButton(template)"/>
                </template>
                <template #remove="scope">
                    <el-button circle plain type="danger" v-auth="'menu:delete'" @click="() => onDeleteButton(scope.row)"/>
                </template>
                <el-table-column label="图标" prop="icon" width="90" align="center">
                    <template #default="scope">
                        <m-icon-select v-model="scope.row.icon" clearable @change="onCreateOrUpdateButton(scope.row)"></m-icon-select>
                    </template>
                </el-table-column>
                <el-table-column label="按钮名称" prop="title">
                    <template #default="scope">
                        <el-input v-model="scope.row.title" placeholder="请输入按钮名称" @change="onCreateOrUpdateButton(scope.row)"/>
                    </template>
                </el-table-column>
                <el-table-column label="授权标识" prop="perms">
                    <template #default="scope">
                        <el-input v-model="scope.row.perms" placeholder="请输入授权标识" @change="onCreateOrUpdateButton(scope.row)"/>
                    </template>
                </el-table-column>
            </form-table>
        </el-col>
    </el-row>
</template>

<script lang="ts" setup>
import {computed, onMounted, reactive, ref, watch} from 'vue'
import MIconSelect from '@/components/select-icon/index.vue'
import FormTable from '@/components/form-table/index.vue'
import {getDictTrim, getPrimaryModuleList} from "@/api/system";
import {service, validator} from "@/utils";
import {ElMessage} from "element-plus";

const props = defineProps({
    menu: {
        type: Array
    },
    node: {
        type: Object
    },
    save: {
        type: Function,
        required: true
    },
    remove: {
        type: Function,
        required: true
    },
    loading: {
        type: Boolean,
        default: false
    }
})

const menus = computed(() => [{menuId: '0', label: '根目录'}, ...props.menu?.slice(0, -1)])

const menuFormRef = ref()
const rules = reactive({
    title: [{required: true, trigger: 'blur', validator: validator}]
})
const form = reactive<any>({
    menuId: null,
    icon: '',
    type: '0',
    title: '',
    parentId: '0',
    perms: '',
    code: 'AdminApplication',
    path: '',
    component: 'PageView',
    orderNum: 0,
    params: null
})

const buttons = ref([]);
const buttonLoading = ref(false);
const buttonDataTemplate = ref({
    menuId: null,
    icon: '',
    type: '1',
    title: '未命名',
    parentId: '',
    perms: '',
    code: '',
});
// 加载按钮数据
function onLoadButtonData() {
    if (props.node) {
        buttonLoading.value = true;
        service.get('/menu', {parentId: props.node.data.menuId, type: '1'}).then(({code, data}) => {
            if (code === 200) {
                buttons.value = data.rows.map((item: any)=> {
                    const temp: {[key:string]:any} = {};
                    Object.keys(form).forEach(key => temp[key] = item[key])
                    return temp;
                })
            } else {
                buttons.value = [];
            }
        }).finally(() => buttonLoading.value = false)
    }
}

// 创建或修改按钮信息
function onCreateOrUpdateButton(data: any) {
    service[data.menuId? 'put':'post']('/menu', data).then(({code}) => {
        code === 200 && onLoadButtonData();
    })
}

// 删除按钮
function onDeleteButton(data: any) {
    service.confirm(`确定对按钮[${data.title}]进行删除操作,该操作不可逆?`, {
        url: '/menu',
        data: {menuIds: [data.menuId]},
        success: onLoadButtonData
    })
}

// 菜单发生变化时更新菜单信息并重新加载按钮数据
watch(()=> props.node, (node: any) => {
    setData(node?.data); // 初始化表单数据
    node && onLoadButtonData(); // 加载按钮数据
})

const enums = reactive<{[key:string]: any}>({});
const onLoadEnumsData = () => {
    Promise.all([getDictTrim('sys_menu', 'type')]).then((rs) => {
        let data = rs[0].data;
        Object.keys(data).forEach((field: string) => {
            enums[field] = Array.from(data[field]).filter((item: any) => item.value !== '1').map((item: any) => {
                item.effect = 'dark';
                switch (item.value) {
                    case '0':item.type = 'primary';break
                    case '1':item.type = 'success';break
                    case '2':item.type = 'warning';break
                }
                return item;
            });
        })

        data = [];
        enums['code'] =  Array.from(data).map((item: any)=> ({label: item.title, value: item.name, uri: item.uri, effect: 'dark'}));
        enums['code'].splice(0, 0, {label: '后台管理系统', value: 'AdminApplication', uri: '', effect: 'dark'});
    })
}
onMounted(() => onLoadEnumsData())

//保存菜单
const onSaveMenu = () => {
    menuFormRef.value.validate((valid: any) => {
        if (valid) {
            if (form.parentId !== props.node?.data.menuId) {
                props.save(form, props.node);
            } else {
                ElMessage.warning(`上级菜单选择错误，不能是移动菜单本身，请选中其他菜单`)
            }
        }
    })
}

//表单注入数据
const setData = async (data: any) => {
    if (data) {
        Object.keys(form).forEach(k => form[k] = data?.[k])
        // 按钮基础数据信息跟随菜单变更而变更
        buttonDataTemplate.value.code = data.code;
        buttonDataTemplate.value.parentId = data.menuId;
    } else {
        form.menuId = null;
    }
}
</script>

<style scoped>
h2 {
    font-size: 17px;
    color: #3c4a54;
    padding: 0 0 30px 0;
}

.buttonList {
    border-left: 1px solid #eee;
}

[data-theme="dark"] h2 {
    color: #fff;
}

[data-theme="dark"] .apilist {
    border-color: #434343;
}

:deep(.el-select-dropdown__footer){
    float: right;
}
</style>
